#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Software : PyCharm
# @Time    : 2024-12-18 11:09
# @Author  : gzh
# @File : CanvasExcel.py

"""
在使用树莓派2B开发过程中,需要对xls或者xlsx数据进行预览但由于硬件资源有限导致通过系统默认软件打开时间特长,
因此通过Canvas进行了简单的数据预览绘制,实际使用过程中需要根据表格形式对draw_line函数进行一定的改动
最简单的使用方法就是将文件中的数据案列读取然后直接写入
"""
from tkinter import Canvas, Scrollbar


class ExcelChart(Canvas):
    def __init__(self, master, len_data=20, **kwargs):
        self.color = '#000000'  # 颜色
        self.scr_w = 25  # 滑块宽度
        self.len_data = len_data  # 数据长度
        self.all_width = 800 - self.scr_w  # 界面有效宽度
        ws = [1, 1, 1, 1, 1, 1]  # 格列宽度比例
        hh = [8, *[5 for _ in range(17)], *[5 for _ in range(self.len_data)]]  # 各行高度比例
        _w = self.all_width / sum(ws)
        self.ww = [i * _w for i in ws]
        self.hh = [i * 5 for i in hh]  # 5: 单位高度
        self.all_height = sum(self.hh)
        kwargs.pop('bg', None)
        kwargs.pop('background', None)
        kwargs.pop('width', None)
        kwargs.pop('height', None)
        kwargs.pop('border', None)
        kwargs.pop('highlightthickness', None)
        super().__init__(master, bg='white', border=0, highlightthickness=0, **kwargs)

        # 创建垂直滚动条
        self.scy = Scrollbar(self, orient="vertical", command=self.yview, width=(self.scr_w - 5))
        self.scy.pack(fill="y", side="right", expand=False)  # 滚动条在右侧，不扩展
        self.configure(yscrollcommand=self.scy.set)

        # 设置初始的滚动区域
        self.scy.bind("<MouseWheel>", self.mouse_bind_y)
        self.bind("<MouseWheel>", self.mouse_bind_y)

    def draw_line(self):  # 绘制表格线条根据不同需求进行调整
        self.create_rectangle(0, 0, self.all_width, self.all_height, width=3, outline=self.color)
        self.create_line(0, 40, self.all_width, 40, width=1, fill=self.color)
        for i in range(1, len(self.hh)):
            self.create_line(0, sum(self.hh[:i]), self.all_width, sum(self.hh[:i]), width=1, fill=self.color)
        for i in range(1, len(self.ww)):
            if i == 1:
                self.create_line(sum(self.ww[:i]), self.hh[0], sum(self.ww[:i]), self.all_height, width=1,
                                 fill=self.color)
            elif i == 2:
                # self.create_line(sum(self.ww[:i]), sum(self.hh[:6]), sum(self.ww[:i]),
                #                  sum(self.hh[:16]), width=1, fill=self.color)
                self.create_line(sum(self.ww[:i]), sum(self.hh[:17]), sum(self.ww[:i]),
                                 self.all_height, width=1, fill=self.color)
            elif i == 3:
                self.create_line(sum(self.ww[:i]), sum(self.hh[:2]), sum(self.ww[:i]),
                                 sum(self.hh[:4]), width=1, fill=self.color)
                self.create_line(sum(self.ww[:i]), sum(self.hh[:5]), sum(self.ww[:i]),
                                 self.all_height, width=1, fill=self.color)
            elif i == 4:
                self.create_line(sum(self.ww[:i]), sum(self.hh[:2]), sum(self.ww[:i]),
                                 self.all_height, width=1, fill=self.color)
            else:
                self.create_line(sum(self.ww[:i]), sum(self.hh[:4]), sum(self.ww[:i]),
                                 sum(self.hh[:5]), width=1, fill=self.color)
                self.create_line(sum(self.ww[:i]), sum(self.hh[:17]), sum(self.ww[:i]),
                                 self.all_height, width=1, fill=self.color)

        self.create_oval(self.all_width + self.scr_w, self.all_height, self.all_width + self.scr_w, self.all_height)
        self.configure(scrollregion=self.bbox("all"))
        self.create_text(self.all_width / 2, 20, text='报告统计', font=("", 20), fill=self.color)

    def write_all(self, idx, text):  # 数据写入
        for i, v in enumerate(text):
            if v == '' or v == '报告统计':
                continue
            elif idx == 1 and i < 17:
                if i == 1:
                    self.create_text(sum(self.ww[:3]), sum(self.hh[:i]) + self.hh[18] / 2,
                                     text=v, font=("", 15), fill=self.color)
                elif i == 4:
                    self.create_text(sum(self.ww[:2]) + self.ww[3] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                                     text=v, font=("", 15), fill=self.color)
                else:
                    self.create_text(sum(self.ww[:2]), sum(self.hh[:i]) + self.hh[18] / 2,
                                     text=v, font=("", 15), fill=self.color)
            elif idx == 4 and i < 17:
                if i == 4:
                    self.create_text(sum(self.ww[:idx]) + self.ww[idx] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                                     text=v, font=("", 15), fill=self.color)
                else:
                    self.create_text(sum(self.ww[:5]), sum(self.hh[:i]) + self.hh[18] / 2,
                                     text=v, font=("", 15), fill=self.color)
            else:
                self.create_text(sum(self.ww[:idx]) + self.ww[idx] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                                 text=v, font=("", 15), fill=self.color)

    def write_A(self, text): # A列数据写入
        # text = ['', '单位', '司机', '机车', '时间', '冲动等级', '一级', '二级', '三级', '四级', '五级', '六级', '七级',
        #          '八级', '九级', '十级', '站数', '序号', *[f'{i + 1}' for i in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            self.create_text(self.ww[0] / 2, sum(self.hh[:i]) + self.hh[18] / 2, text=v, font=("", 15), fill=self.color)

    def write_B(self, text): # B列数据写入
        #         text = ['', '', '', '', '', '冲动范围', '', '', '', '', '', '', '',
        #                  '', '', '', '', '等级', *[f'' for _ in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            elif v == '冲动范围':
                self.create_text(sum(self.ww[:2]), sum(self.hh[:i]) + self.hh[18] / 2,
                                 text=v, font=("", 15), fill=self.color)
            else:
                self.create_text(sum(self.ww[:1]) + self.ww[1] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                                 text=v, font=("", 15), fill=self.color)

    def write_C(self, text): # C列数据写入
        #         text = ['', '', '', '', '', '', '', '', '', '', '', '', '',
        #                  '', '', '', '', '冲动值', *[f'' for _ in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            self.create_text(sum(self.ww[:2]) + self.ww[2] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                             text=v, font=("", 15), fill=self.color)

    def write_D(self, text): # D列数据写入
        #         text = ['', '', '工号', '机车号', '', '冲动次数', '', '', '', '', '', '', '',
        #                 '', '', '', '分数', '时刻', *[f'' for _ in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            self.create_text(sum(self.ww[:3]) + self.ww[3] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                             text=v, font=("", 15), fill=self.color)

    def write_E(self, text): # E列数据写入
        #         text = ['', '', '', '', '标准', '速度范围', '', '', '', '', '', '', '',
        #                 '', '', '', '', '速度', *[f'' for _ in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            elif v == '速度范围':
                self.create_text(sum(self.ww[:5]), sum(self.hh[:i]) + self.hh[18] / 2,
                                 text=v, font=("", 15), fill=self.color)
            else:
                self.create_text(sum(self.ww[:4]) + self.ww[4] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                                 text=v, font=("", 15), fill=self.color)

    def write_F(self, text): # F列数据写入
        # text = ['', '', '', '', '', '', '', '', '', '', '', '', '',
        #         '', '', '', '', '公里标', *[f'' for _ in range(self.len_data)]]
        for i, v in enumerate(text):
            if v == '':
                continue
            self.create_text(sum(self.ww[:5]) + self.ww[5] / 2, sum(self.hh[:i]) + self.hh[18] / 2,
                             text=v, font=("", 15), fill=self.color)

    def mouse_bind_y(self, event):  # 鼠标滚轮滚动事件
        self.configure(scrollregion=self.bbox("all"))
        if event.delta > 0:
            self.yview_scroll(-1, "units")
        else:
            self.yview_scroll(1, "units")


if __name__ == '__main__':
    from tkinter import Tk

    root = Tk()
    root.geometry('800x480+0+0')
    aa = ExcelChart(root)
    aa.draw_line()
    aa.pack(fill="both", expand=True)
    root.mainloop()
